package com.ruoyi.paper.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.stream.Collectors;
import java.util.HashMap;
import java.util.ArrayList;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.errorLib.service.IErrorQuestionService;
import com.ruoyi.paper.domain.*;
import com.ruoyi.paper.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.jxsx.util.CourseStatusUtil;
import org.springframework.beans.factory.annotation.Autowired;
import com.ruoyi.paper.service.IExamPaperService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 实训试卷Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-04-14
 */
@Service
public class ExamPaperServiceImpl implements IExamPaperService 
{
    private static final Logger log = LoggerFactory.getLogger(ExamPaperServiceImpl.class);

    @Autowired
    private ExamPaperMapper examPaperMapper;
    @Autowired
    private ExamLibMapper examLibMapper;
    @Autowired
    private ExamPaperLibMapper examPaperLibMapper;
    @Autowired
    private ExamPaperOptionMapper examPaperOptionMapper;
    @Autowired
    private ExamStudentPaperMapper examStudentPaperMapper;
    @Autowired
    private StudentScoreMapper studentScoreMapper;
    @Autowired
    private ExamFolderMapper examFolderMapper;
    @Autowired
    private ExamOptionMapper examOptionMapper;
    @Autowired
    private IErrorQuestionService errorQuestionService;
    /**
     * 查询实训试卷
     * 
     * @param paperId 实训试卷主键
     * @return 实训试卷
     */
    @Override
    public ExamPaper selectExamPaperByPaperId(String paperId)
    {
        return examPaperMapper.selectExamPaperByPaperId(paperId);
    }

    /**
     * 查询实训试卷列表
     * 
     * @param examPaper 实训试卷
     * @return 实训试卷
     */
    @Override
    public List<ExamPaper> selectExamPaperList(ExamPaper examPaper)
    {
        List<ExamPaper> list = examPaperMapper.selectExamPaperList(examPaper);
        SysUser sysUser= ShiroUtils.getSysUser();
        if(sysUser.getUserType().equals("03")){
            for (ExamPaper paper : list) {
                StudentScore studentScore = new StudentScore();
                studentScore.setUserId(sysUser.getUserId()+"");
                studentScore.setPaperId(paper.getPaperId());
                List<StudentScore> studentScores = studentScoreMapper.selectStudentScoreList(studentScore);
                if(studentScores!=null && studentScores.size()>0){
                    String score=studentScores.get(0).getScore();
                    paper.setScore(score);
                }
            }
        }

        return list;
    }

    /**
     * 新增实训试卷
     * 
     * @param examPaper 实训试卷
     * @return 结果
     */
    @Override
    public int insertExamPaper(ExamPaper examPaper)
    {
        examPaper.setPaperId(IdUtils.fastSimpleUUID());
        examPaper.setStatus("0");
        return examPaperMapper.insertExamPaper(examPaper);
    }

    /**
     * 修改实训试卷
     * 
     * @param examPaper 实训试卷
     * @return 结果
     */
    @Override
    public int updateExamPaper(ExamPaper examPaper)
    {
        return examPaperMapper.updateExamPaper(examPaper);
    }

    /**
     * 批量删除实训试卷
     * 
     * @param paperIds 需要删除的实训试卷主键
     * @return 结果
     */
    @Override
    public int deleteExamPaperByPaperIds(String[] paperIds)
    {
        return examPaperMapper.deleteExamPaperByPaperIds(paperIds);
    }

    /**
     * 删除实训试卷信息
     * 
     * @param paperId 实训试卷主键
     * @return 结果
     */
    @Override
    public int deleteExamPaperByPaperId(String paperId)
    {
        return examPaperMapper.deleteExamPaperByPaperId(paperId);
    }

    /**
     * 根据试卷ID查询试卷规则
     * 
     * @param paperId 试卷ID
     * @return 试卷规则
     */
    @Override
    public ExamFolder selectExamFolderByPaperId(String paperId)
    {
        return examFolderMapper.selectExamFolderByPaperId(paperId);
    }

    /**
     * 根据试卷ID和题目类型查询题目列表
     * 
     * @param paperId 试卷ID
     * @param type 题目类型
     * @return 题目列表
     */
    @Override
    public List<ExamPaperLib> selectExamPaperLibByType(String paperId, String type)
    {
        return examPaperLibMapper.selectExamPaperLibByType(paperId, type);
    }

    /**
     * 根据题目ID查询选项列表
     * 
     * @param libId 题目ID
     * @return 选项列表
     */
    @Override
    public List<ExamPaperOption> selectExamPaperOptionByLibId(String libId)
    {
        return examPaperOptionMapper.selectExamPaperOptionByLibId(libId);
    }

    @Override
    public int smartPaper(ExamFolder examFolder)
    {
        // 1. 检查题库中各类题型的数量是否足够
        int radioCount = examPaperMapper.countExamLibByType("0");
        int checkboxCount = examPaperMapper.countExamLibByType("1");
        int indefiniteCount = examPaperMapper.countExamLibByType("2");
        int subjectiveCount = examPaperMapper.countExamLibByType("3");
        examFolder.setFolderId(IdUtils.fastSimpleUUID());
        if (Integer.parseInt(examFolder.getRadioNum()) > radioCount) {
            throw new IllegalArgumentException("单选题数量不足");
        }
        if (Integer.parseInt(examFolder.getCheckboxNum()) > checkboxCount) {
            throw new IllegalArgumentException("多选题数量不足");
        }
        if (Integer.parseInt(examFolder.getIndefiniteNum()) > indefiniteCount) {
            throw new IllegalArgumentException("不定项题数量不足");
        }
        if (Integer.parseInt(examFolder.getSubjectiveNum()) > subjectiveCount) {
            throw new IllegalArgumentException("主观题数量不足");
        }

        // 2. 计算总分
        int totalScore = Integer.parseInt(examFolder.getRadioTypeScore()) +
                        Integer.parseInt(examFolder.getCheckboxTypeScore()) +
                        Integer.parseInt(examFolder.getIndefiniteTypeScore()) +
                        Integer.parseInt(examFolder.getSubjectiveTypeScore());

        // 3. 随机抽取试题
        List<ExamLib> radioQuestions = examLibMapper.selectRandomExamLibByType("0", Integer.parseInt(examFolder.getRadioNum()));
        List<ExamLib> checkboxQuestions = examLibMapper.selectRandomExamLibByType("1", Integer.parseInt(examFolder.getCheckboxNum()));
        List<ExamLib> indefiniteQuestions = examLibMapper.selectRandomExamLibByType("2", Integer.parseInt(examFolder.getIndefiniteNum()));
        List<ExamLib> subjectiveQuestions = examLibMapper.selectRandomExamLibByType("3", Integer.parseInt(examFolder.getSubjectiveNum()));

        // 4. 保存试卷规则
        examFolder.setTotalScore(String.valueOf(totalScore));
        examPaperMapper.insertExamFolder(examFolder);

        // 5. 保存试卷题目
        int seqNo = 1;
        for (ExamLib question : radioQuestions) {
            ExamPaperLib paperLib = new ExamPaperLib();
            paperLib.setPaperId(examFolder.getPaperId());
            paperLib.setLibId(question.getExamLibId());
            paperLib.setQuestionType("0");
            paperLib.setQuestionBody(question.getQuestionBody());
            paperLib.setRefAnswer(question.getRefAnswer());
            paperLib.setExplanation(question.getExplanation());
            paperLib.setSeqNo((long) seqNo++);
            paperLib.setPaperLibId(IdUtils.fastSimpleUUID());
            examPaperLibMapper.insertExamPaperLib(paperLib);
            // 更新试题被选中次数
            examPaperMapper.updateExamLibNum(question.getExamLibId());
        }

        for (ExamLib question : checkboxQuestions) {
            ExamPaperLib paperLib = new ExamPaperLib();
            paperLib.setPaperId(examFolder.getPaperId());
            paperLib.setLibId(question.getExamLibId());
            paperLib.setQuestionType("1");
            paperLib.setQuestionBody(question.getQuestionBody());
            paperLib.setRefAnswer(question.getRefAnswer());
            paperLib.setExplanation(question.getExplanation());
            paperLib.setSeqNo((long) seqNo++);
            paperLib.setPaperLibId(IdUtils.fastSimpleUUID());
            examPaperLibMapper.insertExamPaperLib(paperLib);
            examPaperMapper.updateExamLibNum(question.getExamLibId());
        }

        for (ExamLib question : indefiniteQuestions) {
            ExamPaperLib paperLib = new ExamPaperLib();
            paperLib.setPaperId(examFolder.getPaperId());
            paperLib.setLibId(question.getExamLibId());
            paperLib.setQuestionType("2");
            paperLib.setPaperLibId(IdUtils.fastSimpleUUID());
            paperLib.setQuestionBody(question.getQuestionBody());
            paperLib.setRefAnswer(question.getRefAnswer());
            paperLib.setExplanation(question.getExplanation());
            paperLib.setSeqNo((long) seqNo++);
            examPaperLibMapper.insertExamPaperLib(paperLib);
            examPaperMapper.updateExamLibNum(question.getExamLibId());
        }

        for (ExamLib question : subjectiveQuestions) {
            ExamPaperLib paperLib = new ExamPaperLib();
            paperLib.setPaperId(examFolder.getPaperId());
            paperLib.setLibId(question.getExamLibId());
            paperLib.setQuestionType("3");
            paperLib.setQuestionBody(question.getQuestionBody());
            paperLib.setRefAnswer(question.getRefAnswer());
            paperLib.setExplanation(question.getExplanation());
            paperLib.setSeqNo((long) seqNo++);
            paperLib.setPaperLibId(IdUtils.fastSimpleUUID());
            examPaperLibMapper.insertExamPaperLib(paperLib);
            examPaperMapper.updateExamLibNum(question.getExamLibId());
        }

        // 6. 更新试卷状态
        ExamPaper examPaper = examPaperMapper.selectExamPaperByPaperId(examFolder.getPaperId());
        examPaper.setStatus(CourseStatusUtil.getCourseStatus(examPaper.getStartTime(),examPaper.getEndTime())+""); // 未开始
        return examPaperMapper.updateExamPaper(examPaper);
    }

    /**
     * 定时更新试卷状态
     * 每5分钟执行一次
     */
    @Scheduled(fixedRate = 120000)
    public void updateExamPaperStatus() {
        try {
            // 查询所有非未发布状态的试卷
            ExamPaper query = new ExamPaper();
            query.setStatus("0"); // 排除未发布状态的试卷
            List<ExamPaper> examPapers = examPaperMapper.selectExamPaperList(query);
            
            for (ExamPaper paper : examPapers) {
                try {
                    // 使用CourseStatusUtil判断当前状态
                    int newStatus = CourseStatusUtil.getCourseStatus(paper.getStartTime(), paper.getEndTime());
                    String currentStatus = paper.getStatus();
                    
                    // 只有当状态发生变化时才更新
                    if (!String.valueOf(newStatus).equals(currentStatus)) {
                        paper.setStatus(String.valueOf(newStatus));
                        examPaperMapper.updateExamPaper(paper);
                        log.info("试卷ID: {} 状态已更新, 从 {} 更新为 {}", 
                            paper.getPaperId(), currentStatus, newStatus);
                    }
                } catch (Exception e) {
                    log.error("更新试卷状态时出错, 试卷ID: " + paper.getPaperId(), e);
                }
            }
        } catch (Exception e) {
            log.error("执行试卷状态更新任务时出错", e);
        }
    }

    @Override
    @Transactional
    public StudentScore saveStudentAnswers(String paperId, String userId, String studentId, Map<String, String> answers, Long duration) {
        // 1. 获取试卷规则
        ExamFolder examFolder = examFolderMapper.selectExamFolderByPaperId(paperId);
        if (examFolder == null) {
            throw new RuntimeException("试卷规则不存在");
        }

        // 2. 保存学生答题记录并计算得分
        int totalScore = 0;
        for (Map.Entry<String, String> entry : answers.entrySet()) {
            String paperLibId = entry.getKey();
            Object answerStr = entry.getValue();
            String answer = null;
            //判断对象是不是集合
            if(answerStr instanceof Collection){
                answer=((Collection)answerStr).stream().map(Object::toString).collect(Collectors.joining(",")).toString();
            }else{
                answer=answerStr.toString();
            }

            // 获取试题信息
            ExamPaperLib examPaperLib = examPaperLibMapper.selectExamPaperLibByPaperLibId(paperLibId);
            if (examPaperLib == null) {
                throw new RuntimeException("试题不存在");
            }

            // 创建学生答题记录
            ExamStudentPaper studentPaper = new ExamStudentPaper();
            studentPaper.setStudentPaperId(IdUtils.fastSimpleUUID());
            studentPaper.setPaperLibId(paperLibId);
            studentPaper.setPaperId(paperId);
            studentPaper.setUserId(userId);
            studentPaper.setAnswer(answer);
            studentPaper.setStatus(1L); // 1表示已保存

            // 计算得分
            String questionType = examPaperLib.getQuestionType();
            String refAnswer = examPaperLib.getRefAnswer();
            String score = "0";
            boolean isRight = false;
            // 根据题目类型处理答案
            if (answer != null) {
                switch (questionType) {
                    case "0": // 单选题 - 直接比较字符串
                        if (answer.equals(refAnswer)) {
                            score = examFolder.getRadioOneScore();
                            totalScore += Integer.parseInt(score);
                            isRight=true;
                        }
                        break;
                    case "1": // 多选题 - 需要比较答案集合
                    case "2": // 不定项题 - 需要比较答案集合
                        // 将答案字符串转换为集合进行比较
                        String[] studentAnswers = answer.split(",");
                        String[] refAnswers = refAnswer.split(",");
                        
                        // 检查答案数量是否相同
                        if (studentAnswers.length == refAnswers.length) {
                            boolean isCorrect = true;
                            // 检查每个答案是否都匹配
                            for (String studentAns : studentAnswers) {
                                boolean found = false;
                                for (String refAns : refAnswers) {
                                    if (studentAns.trim().equals(refAns.trim())) {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found) {
                                    isCorrect = false;
                                    break;
                                }
                            }
                            
                            if (isCorrect) {
                                isRight=true;
                                if ("1".equals(questionType)) {
                                    score = examFolder.getCheckboxOneScore();
                                } else {
                                    score = examFolder.getIndefiniteOneScore();
                                }
                                totalScore += Integer.parseInt(score);
                            }
                        }
                        break;
                    case "3": // 主观题 - 需要人工评分，这里先设置为0分
                        score = "0";
                        isRight=true;
                        break;
                }
            }
            studentPaper.setScore(score);
            if(!isRight){//保存错题
                errorQuestionService.saveStudentErrorQuestion( studentId, Long.parseLong(userId), examPaperLib.getLibId(),  examPaperLib.getQuestionBody(),
                         questionType,answer,  refAnswer);
            }
            // 保存学生答题记录
            examStudentPaperMapper.insertExamStudentPaper(studentPaper);
        }

        // 3. 保存学生成绩
        StudentScore studentScore = new StudentScore();
        studentScore.setScoreId(IdUtils.fastSimpleUUID());
        studentScore.setStudentId(studentId);
        studentScore.setUserId(userId);
        studentScore.setDuration(duration);
        studentScore.setSubmitTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        studentScore.setScore(String.valueOf(totalScore));
        studentScore.setPaperId(paperId);

        studentScoreMapper.insertStudentScore(studentScore);

        return studentScore;
    }

    @Override
    public List<ExamPaper> selectAnsweredPaperList(String studentId) {
        return examPaperMapper.selectAnsweredPaperList(studentId);
    }

    @Override
    public Map<String, Object> selectPaperAnswerDetail(String paperId, String studentId,String userId) {
        Map<String, Object> result = new HashMap<>();
        
        // 1. 获取试卷基本信息
        ExamPaper examPaper = examPaperMapper.selectExamPaperByPaperId(paperId);
        result.put("paper", examPaper);
        
        // 2. 获取学生成绩
        StudentScore studentScore = studentScoreMapper.selectStudentScoreByPaperIdAndStudentId(paperId, studentId);
        result.put("score", studentScore);
        
        // 3. 获取试卷题目列表
        List<ExamPaperLib> paperLibs = examPaperLibMapper.selectExamPaperLibByPaperId(paperId);
        List<Map<String, Object>> questionList = new ArrayList<>();
        
        for (ExamPaperLib paperLib : paperLibs) {
            Map<String, Object> question = new HashMap<>();
            question.put("paperLib", paperLib);
            
            // 获取题目选项
            ExamOption examOption=new ExamOption();
            examOption.setLibId(paperLib.getLibId());
            List<ExamOption> options = examOptionMapper.selectExamOptionList(examOption);
            question.put("options", options);
            
            // 获取学生答题记录
            ExamStudentPaper studentPaper = examStudentPaperMapper.selectExamStudentPaperByPaperLibIdAndUserId(
                paperLib.getPaperLibId(), userId);
            question.put("studentAnswer", studentPaper);
            
            questionList.add(question);
        }
        
        result.put("questions", questionList);
        return result;
    }

    @Override
    public Map<String, Object> getPaperReport(String paperId) {
        Map<String, Object> result = new HashMap<>();

        // 1. 获取试卷基本信息
        ExamPaper examPaper = examPaperMapper.selectExamPaperByPaperId(paperId);
        result.put("paper", examPaper);

        // 2. 获取学生成绩列表
        List<StudentScore> studentScores = studentScoreMapper.selectStudentScoreByPaperId(paperId);

        // 3. 计算平均分
        double avgScore = studentScores.stream()
            .mapToDouble(score -> Double.parseDouble(score.getScore()))
            .average()
            .orElse(0.0);
        result.put("avgScore", String.format("%.2f", avgScore));

        // 4. 处理学生成绩列表
        List<Map<String, Object>> studentList = new ArrayList<>();
        for (int i = 0; i < studentScores.size(); i++) {
            StudentScore score = studentScores.get(i);
            Map<String, Object> studentMap = new HashMap<>();
            studentMap.put("studentId", score.getStudentId());
            studentMap.put("number", score.getStudentNumber());
            studentMap.put("studentName", score.getStudentName());
            studentMap.put("duration", score.getDuration());
            studentMap.put("score", score.getScore());
            studentMap.put("rank", i + 1);
            studentList.add(studentMap);
        }
        result.put("studentList", studentList);

        // 5. 计算成绩分布
        Map<String, Integer> scoreDistribution = new HashMap<>();
        scoreDistribution.put("excellent", 0); // 80-100
        scoreDistribution.put("good", 0);      // 70-79
        scoreDistribution.put("medium", 0);    // 60-69
        scoreDistribution.put("pass", 0);      // 50-59
        scoreDistribution.put("fail", 0);      // 0-49

        for (StudentScore score : studentScores) {
            double scoreValue = Double.parseDouble(score.getScore());
            if (scoreValue >= 80) {
                scoreDistribution.put("excellent", scoreDistribution.get("excellent") + 1);
            } else if (scoreValue >= 70) {
                scoreDistribution.put("good", scoreDistribution.get("good") + 1);
            } else if (scoreValue >= 60) {
                scoreDistribution.put("medium", scoreDistribution.get("medium") + 1);
            } else if (scoreValue >= 50) {
                scoreDistribution.put("pass", scoreDistribution.get("pass") + 1);
            } else {
                scoreDistribution.put("fail", scoreDistribution.get("fail") + 1);
            }
        }
        result.put("scoreDistribution", scoreDistribution);

        // 6. 获取试题列表及统计信息
        List<ExamPaperLib> questions = examPaperLibMapper.selectExamPaperLibByPaperId(paperId);
        List<Map<String, Object>> questionList = new ArrayList<>();
        ExamFolder examFolder=examFolderMapper.selectExamFolderByPaperId(paperId);
        for (ExamPaperLib question : questions) {
            Map<String, Object> questionMap = new HashMap<>();
            questionMap.put("seqNo", question.getSeqNo());
            questionMap.put("questionBody", question.getQuestionBody());

            // 计算该题的平均分和得分率
            List<ExamStudentPaper> studentAnswers = examStudentPaperMapper.selectExamStudentPaperByPaperLibId(question.getPaperLibId());
            double totalScore = studentAnswers.stream()
                .mapToDouble(answer -> Double.parseDouble(answer.getScore()))
                .sum();
            double avgQuestionScore = studentAnswers.isEmpty() ? 0 : totalScore / studentAnswers.size();
           String libSore="";
           if (question.getQuestionType().equals("0")) {
               libSore=examFolder.getRadioOneScore();
           }
            if (question.getQuestionType().equals("1")) {
                libSore=examFolder.getCheckboxOneScore();
            }
            if (question.getQuestionType().equals("2")) {
                libSore=examFolder.getIndefiniteOneScore();
            }
            if (question.getQuestionType().equals("3")) {
                libSore=examFolder.getSubjectiveOneScore();
            }
            double scoreRate=0;
            if(StringUtils.isNotEmpty(libSore)){
                 scoreRate = avgQuestionScore / Double.parseDouble(libSore);
            }
            questionMap.put("avgScore", String.format("%.2f", avgQuestionScore));
            questionMap.put("scoreRate", String.format("%.2f", scoreRate * 100) + "%");
            questionList.add(questionMap);
        }
        result.put("questionList", questionList);

        return result;
    }
}
